From fae60f0c8a255d680d654909c0b73c3c2b7a41e1 Mon Sep 17 00:00:00 2001 From: "cl349@freefall.cl.cam.ac.uk" Date: Wed, 28 Jul 2004 13:45:22 +0000 Subject: [PATCH] bitkeeper revision 1.1108.1.31 (4107adf2vp4n6dnsoTUjick0ruJYIQ) get Linux 2.6 in dom0 working: - tested with e100 driver and nfsroot --- .rootkeys | 5 + linux-2.6.7-xen-sparse/arch/xen/i386/Makefile | 4 +- .../arch/xen/i386/kernel/Makefile | 6 +- .../arch/xen/i386/kernel/pci-dma.c | 39 +++++ .../arch/xen/i386/pci/Makefile | 31 ++++ .../arch/xen/i386/pci/direct.c | 83 +++++++++ .../arch/xen/i386/pci/irq.c | 143 +++++++++++++++ .../include/asm-xen/asm-i386/dma-mapping.h | 163 ++++++++++++++++++ .../include/asm-xen/asm-i386/io.h | 1 + 9 files changed, 470 insertions(+), 5 deletions(-) create mode 100644 linux-2.6.7-xen-sparse/arch/xen/i386/kernel/pci-dma.c create mode 100644 linux-2.6.7-xen-sparse/arch/xen/i386/pci/Makefile create mode 100644 linux-2.6.7-xen-sparse/arch/xen/i386/pci/direct.c create mode 100644 linux-2.6.7-xen-sparse/arch/xen/i386/pci/irq.c create mode 100644 linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h diff --git a/.rootkeys b/.rootkeys index 75f18a9865..8e0900c1d5 100644 --- a/.rootkeys +++ b/.rootkeys @@ -168,6 +168,7 @@ 40faa751_zbZlAmLyQgCXdYekVFdWA linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ioport.c 40f562382aC3_Gt4RG-4ZsfvDRUg3Q linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c 40f56238ue3YRsK52HG7iccNzP1AwQ linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ldt.c +4107adf1cNtsuOxOB4T6paAoY2R2PA linux-2.6.7-xen-sparse/arch/xen/i386/kernel/pci-dma.c 40f56238a8iOVDEoostsbun_sy2i4g linux-2.6.7-xen-sparse/arch/xen/i386/kernel/process.c 40f56238YQIJoYG2ehDGEcdTgLmGbg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c 40f56238nWMQg7CKbyTy0KJNvCzbtg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/signal.c @@ -185,6 +186,9 @@ 40f56239xcNylAxuGsQHwi1AyMLV8w linux-2.6.7-xen-sparse/arch/xen/i386/mm/init.c 41062ab7CjxC1UBaFhOMWWdhHkIUyg linux-2.6.7-xen-sparse/arch/xen/i386/mm/ioremap.c 40f5623906UYHv1rsVUeRc0tFT0dWw linux-2.6.7-xen-sparse/arch/xen/i386/mm/pgtable.c +4107adf12ndy94MidCaivDibJ3pPAg linux-2.6.7-xen-sparse/arch/xen/i386/pci/Makefile +4107adf1WcCgkhsdLTRGX52cOG1vJg linux-2.6.7-xen-sparse/arch/xen/i386/pci/direct.c +4107adf1s5u6249DNPUViX1YNagbUQ linux-2.6.7-xen-sparse/arch/xen/i386/pci/irq.c 40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.7-xen-sparse/arch/xen/kernel/Makefile 40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c 40f56239pYRq5yshPTkv3ujXKc8K6g linux-2.6.7-xen-sparse/arch/xen/kernel/empty.c @@ -204,6 +208,7 @@ 40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.7-xen-sparse/drivers/xen/net/Makefile 405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.6.7-xen-sparse/drivers/xen/net/network.c 40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/desc.h +4107adf1E5O4ztGHNGMzCCNhcvqNow linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h 40f5623anSzpuEHgiNmQ56fIRfCoaQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/e820.h 40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h 40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/hypervisor.h diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/Makefile b/linux-2.6.7-xen-sparse/arch/xen/i386/Makefile index c06c8af0c1..aa0870f67b 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/Makefile +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/Makefile @@ -72,13 +72,13 @@ core-y += arch/xen/i386/kernel/ \ # \ # arch/xen/$(mcore-y)/ drivers-$(CONFIG_MATH_EMULATION) += arch/i386/math-emu/ -drivers-$(CONFIG_PCI) += arch/i386/pci/ +drivers-$(CONFIG_PCI) += arch/xen/i386/pci/ # must be linked after kernel/ drivers-$(CONFIG_OPROFILE) += arch/i386/oprofile/ drivers-$(CONFIG_PM) += arch/i386/power/ # for clean -obj- += kernel/ +obj- += kernel/ mm/ pci/ #obj- += ../../i386/lib/ ../../i386/mm/ #../../i386/$(mcore-y)/ #obj- += ../../i386/pci/ ../../i386/oprofile/ ../../i386/power/ diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/Makefile b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/Makefile index 816fcaa096..f867dc9919 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/Makefile +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/Makefile @@ -8,12 +8,12 @@ CFLAGS += -Iarch/$(XENARCH)/kernel extra-y := head.o init_task.o vmlinux.lds.s -obj-y := traps.o irq.o ldt.o setup.o entry.o time.o process.o signal.o \ - i386_ksyms.o +obj-y := traps.o irq.o ldt.o setup.o entry.o time.o pci-dma.o process.o \ + signal.o i386_ksyms.o c-obj-y := semaphore.o vm86.o \ ptrace.o ioport.o sys_i386.o \ - pci-dma.o i387.o dmi_scan.o bootflag.o \ + i387.o dmi_scan.o bootflag.o \ doublefault.o s-obj-y := diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/pci-dma.c b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/pci-dma.c new file mode 100644 index 0000000000..ab83af48ba --- /dev/null +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/pci-dma.c @@ -0,0 +1,39 @@ +/* + * Dynamic DMA mapping support. + * + * On i386 there is no hardware dynamic DMA address translation, + * so consistent alloc/free are merely page allocation/freeing. + * The rest of the dynamic DMA mapping interface is implemented + * in asm/pci.h. + */ + +#include +#include +#include +#include +#include + +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, int gfp) +{ + void *ret; + /* ignore region specifiers */ + gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); + + if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) + gfp |= GFP_DMA; + + ret = (void *)__get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + } + return ret; +} + +void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, get_order(size)); +} diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/pci/Makefile b/linux-2.6.7-xen-sparse/arch/xen/i386/pci/Makefile new file mode 100644 index 0000000000..175f5f4819 --- /dev/null +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/pci/Makefile @@ -0,0 +1,31 @@ +XENARCH := $(subst ",,$(CONFIG_XENARCH)) + +CFLAGS += -Iarch/$(XENARCH)/pci + +c-obj-y := i386.o + +c-obj-$(CONFIG_PCI_BIOS) += pcbios.o +c-obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o +obj-$(CONFIG_PCI_DIRECT) += direct.o + +c-pci-y := fixup.o +c-pci-$(CONFIG_ACPI_PCI) += acpi.o +c-pci-y += legacy.o +pci-y += irq.o + +c-pci-$(CONFIG_X86_VISWS) := visws.o fixup.o +pci-$(CONFIG_X86_VISWS) := +c-pci-$(CONFIG_X86_NUMAQ) := numa.o +pci-$(CONFIG_X86_NUMAQ) := irq.o + +obj-y += $(pci-y) +c-obj-y += $(c-pci-y) common.o + +c-link := + +$(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)): + @ln -fsn $(srctree)/arch/i386/pci/$(notdir $@) $@ + +obj-y += $(c-obj-y) + +clean-files += $(patsubst %.o,%.c,$(c-obj-y) $(c-obj-) $(c-link)) diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/pci/direct.c b/linux-2.6.7-xen-sparse/arch/xen/i386/pci/direct.c new file mode 100644 index 0000000000..661221379b --- /dev/null +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/pci/direct.c @@ -0,0 +1,83 @@ +/* + * direct.c - Low-level direct PCI config space access + */ + +#include +#include +#include "pci.h" + +#include +#include + +/* + * Functions for accessing PCI configuration space with type xen accesses + */ + +static int pci_conf_read (int seg, int bus, int devfn, int reg, int len, u32 *value) +{ + unsigned long flags; + physdev_op_t op; + int ret; + + if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) + return -EINVAL; + + spin_lock_irqsave(&pci_config_lock, flags); + + op.cmd = PHYSDEVOP_PCI_CFGREG_READ; + op.u.pci_cfgreg_read.bus = bus; + op.u.pci_cfgreg_read.dev = (devfn & ~0x7) >> 3; + op.u.pci_cfgreg_read.func = devfn & 0x7; + op.u.pci_cfgreg_read.reg = reg; + op.u.pci_cfgreg_read.len = len; + + ret = HYPERVISOR_physdev_op(&op); + if (ret == 0) + *value = op.u.pci_cfgreg_read.value; + + spin_unlock_irqrestore(&pci_config_lock, flags); + + return ret; +} + +static int pci_conf_write (int seg, int bus, int devfn, int reg, int len, u32 value) +{ + unsigned long flags; + physdev_op_t op; + int ret; + + if ((bus > 255) || (devfn > 255) || (reg > 255)) + return -EINVAL; + + spin_lock_irqsave(&pci_config_lock, flags); + + op.cmd = PHYSDEVOP_PCI_CFGREG_WRITE; + op.u.pci_cfgreg_write.bus = bus; + op.u.pci_cfgreg_write.dev = (devfn & ~0x7) >> 3; + op.u.pci_cfgreg_write.func = devfn & 0x7; + op.u.pci_cfgreg_write.reg = reg; + op.u.pci_cfgreg_write.len = len; + op.u.pci_cfgreg_write.value = value; + + ret = HYPERVISOR_physdev_op(&op); + + spin_unlock_irqrestore(&pci_config_lock, flags); + + return ret; +} + +struct pci_raw_ops pci_direct_xen = { + .read = pci_conf_read, + .write = pci_conf_write, +}; + + +static int __init pci_direct_init(void) +{ + + printk(KERN_INFO "PCI: Using configuration type Xen\n"); + raw_pci_ops = &pci_direct_xen; + return 0; +} + +arch_initcall(pci_direct_init); diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/pci/irq.c b/linux-2.6.7-xen-sparse/arch/xen/i386/pci/irq.c new file mode 100644 index 0000000000..f6d49f837c --- /dev/null +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/pci/irq.c @@ -0,0 +1,143 @@ +/* + * Low-Level PCI Support for PC -- Routing of Interrupts + * + * (c) 1999--2000 Martin Mares + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pci.h" + +#include +#include + +int broken_hp_bios_irq9; + +/* + * Never use: 0, 1, 2 (timer, keyboard, and cascade) + * Avoid using: 13, 14 and 15 (FP error and IDE). + * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse) + */ +unsigned int pcibios_irq_mask = 0xfff8; + +static int pirq_penalty[16] = { + 1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000, + 0, 0, 0, 0, 1000, 100000, 100000, 100000 +}; + +int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; + + +static int __init pcibios_irq_init(void) +{ + int bus; + physdev_op_t op; + + DBG("PCI: IRQ init\n"); + + if (pcibios_enable_irq || raw_pci_ops == NULL) + return 0; + + op.cmd = PHYSDEVOP_PCI_PROBE_ROOT_BUSES; + if (HYPERVISOR_physdev_op(&op) != 0) { + printk(KERN_WARNING "PCI: System does not support PCI\n"); + return 0; + } + + printk(KERN_INFO "PCI: Probing PCI hardware\n"); + for (bus = 0; bus < 256; bus++) + if (test_bit(bus, (unsigned long *) + &op.u.pci_probe_root_buses.busmask[0])) + (void)pcibios_scan_root(bus); + + pcibios_enable_irq = pirq_enable_irq; + + return 0; +} + +subsys_initcall(pcibios_irq_init); + + +void pcibios_penalize_isa_irq(int irq) +{ + /* + * If any ISAPnP device reports an IRQ in its list of possible + * IRQ's, we try to avoid assigning it to PCI devices. + */ + pirq_penalty[irq] += 100; +} + +int pirq_enable_irq(struct pci_dev *dev) +{ + int err; + u8 pin; + physdev_op_t op; + + /* Inform Xen that we are going to use this device. */ + op.cmd = PHYSDEVOP_PCI_INITIALISE_DEVICE; + op.u.pci_initialise_device.bus = dev->bus->number; + op.u.pci_initialise_device.dev = PCI_SLOT(dev->devfn); + op.u.pci_initialise_device.func = PCI_FUNC(dev->devfn); + if ( (err = HYPERVISOR_physdev_op(&op)) != 0 ) + return err; + + /* Now we can bind to the very final IRQ line. */ + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &pin); + dev->irq = pin; + + /* Sanity-check that an interrupt-producing device is routed + * to an IRQ. */ + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (pin != 0) { + if (dev->irq != 0) + printk(KERN_INFO "PCI: Obtained IRQ %d for device %s\n", + dev->irq, dev->slot_name); + else + printk(KERN_WARNING "PCI: No IRQ known for interrupt " + "pin %c of device %s.\n", 'A' + pin - 1, + dev->slot_name); + } + + return 0; +} + +int pci_vector_resources(int last, int nr_released) +{ + int count = nr_released; + + int next = last; + int offset = (last % 8); + + while (next < FIRST_SYSTEM_VECTOR) { + next += 8; +#ifdef CONFIG_X86_64 + if (next == IA32_SYSCALL_VECTOR) + continue; +#else + if (next == SYSCALL_VECTOR) + continue; +#endif + count++; + if (next >= FIRST_SYSTEM_VECTOR) { + if (offset%8) { + next = FIRST_DEVICE_VECTOR + offset; + offset++; + continue; + } + count--; + } + } + + return count; +} diff --git a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h new file mode 100644 index 0000000000..9d2f2cedd6 --- /dev/null +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h @@ -0,0 +1,163 @@ +#ifndef _ASM_I386_DMA_MAPPING_H +#define _ASM_I386_DMA_MAPPING_H + +#include +#include +#include + +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) + +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, int flag); + +void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); + +static inline dma_addr_t +dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + flush_write_buffers(); + return virt_to_bus(ptr); +} + +static inline void +dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +static inline int +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction) +{ + int i; + + BUG_ON(direction == DMA_NONE); + + for (i = 0; i < nents; i++ ) { + BUG_ON(!sg[i].page); + + sg[i].dma_address = page_to_machine(sg[i].page) + sg[i].offset; + } + + flush_write_buffers(); + return nents; +} + +static inline dma_addr_t +dma_map_page(struct device *dev, struct page *page, unsigned long offset, + size_t size, enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + return page_to_machine(page) + offset; +} + +static inline void +dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + + +static inline void +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +static inline void +dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ +} + +static inline void +dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ + flush_write_buffers(); +} + +static inline void +dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ +} + +static inline void +dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + flush_write_buffers(); +} + +static inline void +dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ +} + +static inline void +dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ + flush_write_buffers(); +} + +static inline int +dma_mapping_error(dma_addr_t dma_addr) +{ + return 0; +} + +static inline int +dma_supported(struct device *dev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, + * so we can't guarantee allocations that must be + * within a tighter range than GFP_DMA.. + */ + if(mask < 0x00ffffff) + return 0; + + return 1; +} + +static inline int +dma_set_mask(struct device *dev, u64 mask) +{ + if(!dev->dma_mask || !dma_supported(dev, mask)) + return -EIO; + + *dev->dma_mask = mask; + + return 0; +} + +static inline int +dma_get_cache_alignment(void) +{ + /* no easy way to get cache size on all x86, so return the + * maximum possible, to be safe */ + return (1 << L1_CACHE_SHIFT_MAX); +} + +#define dma_is_consistent(d) (1) + +static inline void +dma_cache_sync(void *vaddr, size_t size, + enum dma_data_direction direction) +{ + flush_write_buffers(); +} + +#endif diff --git a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/io.h b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/io.h index 81482eb3f4..321d4788e1 100644 --- a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/io.h +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/io.h @@ -86,6 +86,7 @@ static inline void * phys_to_virt(unsigned long address) * Change "struct page" to physical address. */ #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) +#define page_to_machine(page) (phys_to_machine(page_to_phys(page))) extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); -- 2.30.2